package com.base.util;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class HttpClient {

    //User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
    private final static ThreadLocal<Map<String,Object>> threadLocal = new ThreadLocal<Map<String, Object>>();

    private static String cookie;

    public static void request(String u,String body,OutputStream contentOutputtream) throws Exception{
        Map<String,Object> param = getContent();
        String method=(String) param.get(METHOD);
        if(method==null){
            method="GET";
        }
        if("GET".equalsIgnoreCase(method)){
            Map<String,Object> pBody= (Map<String, Object>) param.get(BODY);
            if(pBody!=null){
                StringBuilder sb = new StringBuilder(u);
                sb.append("?");
                boolean isFirst=true;
                for(Map.Entry<String,Object> e:pBody.entrySet()){
                    if(!isFirst) sb.append("&");
                    sb.append(e.getKey());
                    if(e.getValue()!=null){
                        sb.append("=").append(e.getValue().toString());
                    }
                    if(isFirst) isFirst=false;
                }
                u=sb.toString();
            }
        }
        URL url = new URL(u);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod(method);
        Map<String,String> head= (Map<String, String>) param.get(HEAD);
        if(head!=null){
            for(Map.Entry<String,String> e:head.entrySet()){
                connection.setRequestProperty(e.getKey(),e.getValue());
            }
        }
        if(cookie!=null){
            connection.setRequestProperty("cookie",cookie);
        }
        if("POST".equalsIgnoreCase(method)){
            if(body==null){
                Map<String,Object> pBody= (Map<String, Object>) param.get(BODY);
                if(pBody!=null){
                    body = JacksonUtil.objToJson(pBody);
                }
            }
            if(contentOutputtream!=null) connection.setDoInput(true);
            if(body!=null){
                OutputStream os = null;
                try{
                    connection.setDoOutput(true);
                    os = connection.getOutputStream();
                    os.write(body.getBytes("UTF-8"));
                    os.flush();
                }catch (Exception e){
                    throw e;
                }finally {
                    try{
                        os.close();
                    }catch (Exception e1){}
                    try{
                        connection.disconnect();
                    }catch (Exception e1){}
                }
            }
        }
        cookie=connection.getHeaderField("Set-Cookie");
        if(contentOutputtream!=null){
            InputStream is=null;
            try{
                is = connection.getInputStream();
                byte readContent[] = new byte[1024];
                int read;
                while((read=is.read(readContent))>-1){
                    contentOutputtream.write(readContent,0,read);
                }
            }catch (Exception e){
                throw e;
            }finally {
                try{
                    is.close();
                }catch (Exception e2){}

                try{
                    contentOutputtream.close();
                }catch (Exception e2){}

                try{
                    connection.disconnect();
                }catch (Exception e2){}
            }
        }
    }


    public static void addHead(String key,String value){
        Map<String,Object> map = getContent();
        Map<String,String> param= (Map<String, String>) map.get(HEAD);
        if(param==null){
            param=new HashMap<>();
            map.put("head",param);
        }
        String old=  param.get(key);
        if(old!=null){
            value=old+";"+value;
        }
        param.put(key,value);
    }

    public static void addProperty(String key,Object value){
        Map<String,Object> map = getContent();
        Map<String,Object> param= (Map<String, Object>) map.get(BODY);
        if(param==null){
            param=new HashMap<>();
            map.put("body",param);
        }
        param.put(key,value);
    }

    public static void clearHead(){
        Map<String,Object> map = getContent();
        if(map!=null){
            map.remove(HEAD);
        }
    }
    public static void clearBody(){
        Map<String,Object> map = getContent();
        if(map!=null){
            map.remove(BODY);
        }
    }
    public static void clearAll(){
        Map<String,Object> map = getContent();
        if(map!=null){
            map.remove(HEAD);
            map.remove(BODY);
        }
    }

    public static void setRequestMethod(String method){
        Map<String,Object> map = getContent();
        map.put(METHOD,method);
    }

    private static Map<String,Object> getContent(){
        Map<String,Object> map = threadLocal.get();
        if(map==null){
            map = new HashMap<>();
            threadLocal.set(map);
        }
        return map;
    }


    private static final String HEAD="head";
    private static final String BODY="body";
    private static final String METHOD="method";

    public static final String HEAD_USER_AGENT="User-Agent";
    public static final String AGENT_CHROME_HEAD="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";

    public static final String HEAD_CONTENT_TYPE="content-type";
    public static final String CONTENT_TYPE_APPLICATION_JSON="application/json";
    public static final String CONTENT_TYPE_APPLICATION_FORM="application/x-www-form-urlencoded";


    public static void main(String args[]) throws Exception{
        addHead(HEAD_USER_AGENT,AGENT_CHROME_HEAD);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        request("https://www.baidu.com",null,bos);
        byte b[] = bos.toByteArray();
        bos.close();
        String str = new String (b,"UTF-8");
        System.out.println(str);
    }
}
